﻿using System;
using System.Collections.Generic;
using System.Text;


namespace Modelo
{
    [Serializable]
    public class LopezReggaeAlado : Enemigo
    {

        private int velInicial;

        public LopezReggaeAlado(Posicion posInicial, int tamanio, Mapa mapaCreador)
            : base(posInicial, tamanio, mapaCreador)
        {
            resistencia = 5;            //menos resistencia que el lopez reggae común
            ultDirX = 0;
            ultDirY = 1;
            velInicial = (velActual-1); //va más lento ya que camina por los muros
            comportamiento = new ConductaLopezReggaeAlado();
            this.bomba = typeof(Molotov);
        }

        public override void movimientoAI()
        {  
            //Genera un random y se mueve hacia allí, no se fija si hay paredes ya que le es indiferente   
            if (new Random().NextDouble() < 0.9)
            {
                mover(ultDirX, ultDirY);
                return;
            }
            else
            {
                int direccion = new Random().Next(100);
                if (direccion <= 25)
                {
                    ultDirY = 1;
                    ultDirX = 0;
                }
                else if (direccion > 0.25 && direccion <= 50)
                {
                    ultDirY = -1;
                    ultDirX = 0;
                }
                else if (direccion > 0.5 && direccion <= 75)
                {
                    ultDirX = 1;
                    ultDirY = 0;
                }
                else
                {
                    ultDirX = -1;
                    ultDirY = 0;
                }

                mover(ultDirX, ultDirY);
                return;
            }
        }


        #region Movimiento

        public override void mover(int dirx, int diry)
        {
            //Las dir son -1, 1 o 0. Solo indican el sentido en que se esta moviendo.
            int nuevoX = posicion.getX();
            int nuevoY = posicion.getY();
            //Si me estoy moviendo para arriba:
            if (diry == -1)
            {
                if (cornerSupIzqCaminable(new Posicion(posicion.getX(), posicion.getY() + velActual * diry)) && cornerSupDerCaminable(new Posicion(posicion.getX(), posicion.getY() + velActual * diry)))
                {
                    nuevoY += velActual * diry;
                }
                else
                {
                    //Lo pongo contra la pared de arriba.
                    int celdaY = posicion.getY() / mapa.getTamCelda();
                    nuevoY = celdaY * mapa.getTamCelda() + radio;
                    ultDirY = 1;
                }
            }
            //Si me estoy moviendo para abajo:
            else if (diry == 1)
            {
                if (cornerInfIzqCaminable(new Posicion(posicion.getX(), posicion.getY() + velActual * diry)) && cornerInfDerCaminable(new Posicion(posicion.getX(), posicion.getY() + velActual * diry)))
                {
                    nuevoY += velActual * diry;
                }
                else
                {
                    //Lo pongo contra la pared de abajo.
                    int celdaY = posicion.getY() / mapa.getTamCelda();
                    nuevoY = (celdaY + 1) * mapa.getTamCelda() - radio;
                    ultDirY = -1;
                }
            }
            //Si me estoy moviendo para la izquierda:
            else if (dirx == -1)
            {
                if (cornerInfIzqCaminable(new Posicion(posicion.getX() + velActual * dirx, posicion.getY())) && cornerSupIzqCaminable(new Posicion(posicion.getX() + velActual * dirx, posicion.getY())))
                {
                    nuevoX += velActual * dirx;
                }
                else
                {
                    //Lo pongo contra la pared de la izquierda
                    int celdaX = posicion.getX() / mapa.getTamCelda();
                    nuevoX = celdaX * mapa.getTamCelda() + radio;
                    ultDirX = 1;
                }
            }
            //Si me estoy moviendo para la derecha:
            else if (dirx == 1)
            {
                if (cornerInfDerCaminable(new Posicion(posicion.getX() + velActual * dirx, posicion.getY())) && cornerSupDerCaminable(new Posicion(posicion.getX() + velActual * dirx, posicion.getY())))
                {
                    nuevoX += velActual * dirx;
                }
                else
                {
                    //Lo pongo contra la pared de la derecha
                    int celdaX = posicion.getX() / mapa.getTamCelda();
                    nuevoX = (celdaX + 1) * mapa.getTamCelda() - radio;
                    ultDirX = -1;
                }
            }
            posicion = new Posicion(nuevoX, nuevoY);
            return;
        }

        protected override bool cornerInfIzqCaminable(Posicion pos)
        {
            //Devuelve true o false de acuerdo a si el corner inferior izquierdo de la figura es caminable en la posicion x e y 
            //recibida es caminable o no.

            int downY = (int)Math.Floor((double)(pos.getY() + radio - 1) / mapa.getTamCelda());
            int izqX = (int)Math.Floor((double)(pos.getX() - radio) / mapa.getTamCelda());
            //Me fijo de estar dentro de los limites del mapa.
            if (downY < 0 || downY >= mapa.obtenerCeldasY()) return false;
            if (izqX < 0 || izqX >= mapa.obtenerCeldasX()) return false;
            //Finalmente me fijo si esa celda es caminable.
            return true;
        }

        protected override bool cornerInfDerCaminable(Posicion pos)
        {
            //Devuelve true o false de acuerdo a si el corner inferior izquierdo de la figura es caminable en la posicion x e y 
            //recibida es caminable o no.
            int downY = (int)Math.Floor((double)(pos.getY() + radio - 1) / mapa.getTamCelda());
            int derX = (int)Math.Floor((double)(pos.getX() + radio - 1) / mapa.getTamCelda());
            //Me fijo de estar dentro de los limites del mapa.
            if (downY < 0 || downY >= mapa.obtenerCeldasY()) return false;
            if (derX < 0 || derX >= mapa.obtenerCeldasX()) return false;
            //Finalmente me fijo si esa celda es caminable.
            return true;
        }

        protected override bool cornerSupDerCaminable(Posicion pos)
        {
            //Devuelve true o false de acuerdo a si el corner superior derecho de la figura es caminable en la posicion x e y 
            //recibida es caminable o no.
            int upY = (int)Math.Floor((double)(pos.getY() - radio) / mapa.getTamCelda());
            int derX = (int)Math.Floor((double)(pos.getX() + radio - 1) / mapa.getTamCelda());
            //Me fijo de estar dentro de los limites del mapa.
            if (upY < 0 || upY >= mapa.obtenerCeldasY()) return false;
            if (derX < 0 || derX >= mapa.obtenerCeldasX()) return false;
            //Finalmente me fijo si esa celda es caminable.
            return true;
        }

        protected override bool cornerSupIzqCaminable(Posicion pos)
        {
            //Devuelve true o false de acuerdo a si el corner superior izquierdo de la figura es caminable en la posicion x e y 
            //recibida es caminable o no.
            int upY = (int)Math.Floor((double)(pos.getY() - radio) / mapa.getTamCelda());
            int izqX = (int)Math.Floor((double)(pos.getX() - radio) / mapa.getTamCelda());
            //Me fijo de estar dentro de los limites del mapa.
            if (upY < 0 || upY >= mapa.obtenerCeldasY()) return false;
            if (izqX < 0 || izqX >= mapa.obtenerCeldasX()) return false;
            //Finalmente me fijo si esa celda es caminable.
            return true;
        }

        #endregion
    }
}
